//@author A0096759E

/**
 * Deserializes Google Calendar JSON Objects into ScheduleEvents
 */

package googlecal;

import java.lang.reflect.Type;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import storage.ScheduleEvent;

import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;

public class GoogleCalendarItemDeserializer implements JsonDeserializer<ScheduleEvent> {

	private static final int EVENT_TYPE_TIMED = 2;
	private static final String EVENT_TIME_START_MIDNIGHT = "0000";
	private static final String EVENT_TIME_END_MIDNIGHT = "2359";
	
	private static final String LIFESHELF_TASK_UNNAMED = "Unnamed Event";
	private static final Object LIFESHELF_STRING_TRUE = "true";
	
	private static final String KEYWORD_ID = "id";
	private static final String KEYWORD_SUMMARY = "summary";
	private static final String KEYWORD_EXTENDED_PROPERTIES = "extendedProperties";
	private static final String KEYWORD_EVENT_TYPE = "eventType";
	private static final String KEYWORD_LOCALID = "localID";
	private static final String KEYWORD_ISDONE = "isDone";
	private static final String KEYWORD_DATETIME = "dateTime";
	private static final String KEYWORD_START = "start";
	private static final String KEYWORD_DATE = "date";
	private static final String KEYWORD_END = "end";
	private static final String KEYWORD_UPDATED = "updated";
	private static final String KEYWORD_PRIVATE = "private";
	
	private static final String DATETIME_FORMAT_LOCAL_DATE = "ddMMyyyy";
	private static final String DATETIME_FORMAT_TIME = "HHmm";
	private static final String DATETIME_FORMAT_GCAL_DATE = "yyyy-MM-dd";
	private static final String DATETIME_FORMAT_GCAL_DATETIME = "yyyy-MM-dd'T'HH:mm:ssZZ";
	
	  @Override
	  public ScheduleEvent deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context)
	      throws JsonParseException {
	    final JsonObject jsonObject = json.getAsJsonObject();

	    final ScheduleEvent googleCalendarItem = new ScheduleEvent();
	    googleCalendarItem.setGoogleUID(jsonObject.get(KEYWORD_ID).getAsString());
		googleCalendarItem.setType(EVENT_TYPE_TIMED);
	    
	    JsonElement summary = jsonObject.get(KEYWORD_SUMMARY);
	    if (summary != null) {
	    	googleCalendarItem.setName(summary.getAsString());
	    } else {
	    	googleCalendarItem.setName(LIFESHELF_TASK_UNNAMED);
	    }
	    
	    
	    //Do the Private Items
	    if (jsonObject.getAsJsonObject(KEYWORD_EXTENDED_PROPERTIES) != null) {
		    JsonObject privateItems = jsonObject.getAsJsonObject(KEYWORD_EXTENDED_PROPERTIES).getAsJsonObject(KEYWORD_PRIVATE);
		    if (privateItems.get(KEYWORD_EVENT_TYPE) != null) {
			    int eventType = Integer.parseInt(privateItems.get(KEYWORD_EVENT_TYPE).getAsString());
			    googleCalendarItem.setType(eventType);
		    }
		    
		    if (privateItems.get(KEYWORD_LOCALID) != null) {
		    	googleCalendarItem.setUID(privateItems.get(KEYWORD_LOCALID).getAsString());
		    }
		    
		    if (privateItems.get(KEYWORD_ISDONE) != null) {
			    String isDone = privateItems.get(KEYWORD_ISDONE).getAsString();
			    try {
			    	if (isDone.equals(LIFESHELF_STRING_TRUE)) googleCalendarItem.setIsDone();
			    } catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		    }
	    }
	    

    	DateTimeFormatter formatter = DateTimeFormat.forPattern(DATETIME_FORMAT_GCAL_DATETIME);
	    String startDate = null;
	    JsonElement startTime = jsonObject.getAsJsonObject(KEYWORD_START).get(KEYWORD_DATETIME);
	    if (startTime != null) {
	    	DateTime googleDateTime = formatter.parseDateTime(jsonObject.getAsJsonObject(KEYWORD_START).get(KEYWORD_DATETIME).getAsString());
	    	googleCalendarItem.setStartTime(googleDateTime.toString(DATETIME_FORMAT_TIME));
	    	startDate = googleDateTime.toString(DATETIME_FORMAT_LOCAL_DATE);
	    } else {
		    DateTimeFormatter dateformatter = DateTimeFormat.forPattern(DATETIME_FORMAT_GCAL_DATE);
		    DateTime googleDateTime = dateformatter.parseDateTime(jsonObject.getAsJsonObject(KEYWORD_START).get(KEYWORD_DATE).getAsString());
		    googleCalendarItem.setDate(googleDateTime.toString(DATETIME_FORMAT_LOCAL_DATE));
		    googleCalendarItem.setStartTime(EVENT_TIME_START_MIDNIGHT);
		    googleCalendarItem.setEndTime(EVENT_TIME_END_MIDNIGHT);
	    }
	    
	    JsonElement engoogleDateTimeime = jsonObject.getAsJsonObject(KEYWORD_END).get(KEYWORD_DATETIME);
	    if (engoogleDateTimeime != null) {
	    	DateTime googleDateTime = formatter.parseDateTime(jsonObject.getAsJsonObject(KEYWORD_END).get(KEYWORD_DATETIME).getAsString());
			DateTimeFormatter dateFormat = DateTimeFormat.forPattern(DATETIME_FORMAT_LOCAL_DATE);
	    	googleCalendarItem.setDate(googleDateTime.toString(DATETIME_FORMAT_LOCAL_DATE));
	    	googleCalendarItem.setEndTime(googleDateTime.toString(DATETIME_FORMAT_TIME));
	    	if (startDate != null && dateFormat.parseDateTime(googleCalendarItem.getDate()).isAfter(dateFormat.parseDateTime(startDate))) {
	    		googleCalendarItem.setStartTime(EVENT_TIME_START_MIDNIGHT);
	    	}
	    }

	    googleCalendarItem.setUpdated(jsonObject.get(KEYWORD_UPDATED).getAsString());
	    return googleCalendarItem;
	  }

}
